package gui;

import entity.FileMeta;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.GridPane;
import javafx.stage.DirectoryChooser;
import javafx.stage.Window;
import service.SearchService;

import java.io.File;
import java.net.URL;
import java.util.List;
import java.util.ResourceBundle;

public class GUIController implements Initializable {
    @FXML
    private GridPane gridPane;

    @FXML
    private Button button;

    @FXML
    private Label label;

    @FXML
    private TextField textField;

    // 此处的 TableView 表示一个表格，一个表格里就有很多列，每一行又有很多列，所以就把 TableView 视为一个集合类，
    // 集合里面存放的是FileMeta。每一个元素都是一个对象，元素的对象里的属性，就和界面表格的列相匹配
    @FXML
    private TableView<FileMeta> tableView;

    // Controller 里面的属性，不一定是界面上的元素
    private SearchService searchService = null;

    // 程序在加载 GUIController 的时候会自动加载 initialize() 方法
    @Override
    public void initialize(URL location, ResourceBundle resources) {
        /*
        在这里给输入框加入一个 监听器
        需要指定，是针对 text 这个内容属性来监听
         */
        textField.textProperty().addListener(new ChangeListener<String>() {
            @Override
            public void changed(ObservableValue<? extends String> observable,
                                String oldValue, String newValue) {
                /*
                  这个方法，就会在每次用户修改输入框内容的时候，就被自动调用到
                  oldValue 输入框被改之前，旧的值
                  newValue 输入框改完之后，新的值
                  此处需要根据这个新的值，来重新进行查询操作
                 */
                freshTable(newValue);
            }
        });
    }

    /**
     * 重新查询数据库，把查询的结果设置到界面表格中
     * @param query
     */
    private void freshTable(String query) {
        // 查询操作，依赖这个 SearchService 对象的
        if(searchService == null) {
            System.out.println("searchService 尚未初始化，不能查询！");
            return;
        }
        // 先把之前的表格中旧的数据消除到。需要拿到 tableView 内部的集合类
        ObservableList<FileMeta> fileMetas = tableView.getItems();
        // 清空之前的内容
        fileMetas.clear();
        // 查询结果集合 results
        List<FileMeta> results = searchService.search(query);
        // 把查询结果添加到 tableView 之中
        fileMetas.addAll(results);
    }

    /**
     * 使用这个方法，作为鼠标点击事件的回调方法
     * @param mouseEvent 这个方法需要一个 mouseEvent 的参数
     */
    public void choose(MouseEvent mouseEvent) {
//        System.out.println("点击按钮");
        // 先创建出一个 目录选择器对象
        DirectoryChooser directoryChooser = new DirectoryChooser();
        // 还需要把这个对话框显示出来 ---- getWindow() 窗口 -> getScene() 场景 -> gridPane 具体元素
        Window window = gridPane.getScene().getWindow();
        // 弹出对话框
        File file = directoryChooser.showDialog(window);
        if(file == null) {
            System.out.println("当前用户选择的路径为 空");
            return;
        }
        System.out.println(file.getAbsolutePath());

        // 让用户选择的路径，显示到 label 标签中
        label.setText(file.getAbsolutePath());

        // 判定一下当前 searchService 是否为 null，如果非空，就说明现在不是程序首次扫描
        // 就应该停止上次的扫描任务
        if(searchService != null) {
            searchService.shutdown();
        }

        // 让用户选择路径，是为了希望程序对指定路径进行扫描，把对应的数据加入到数据库中
        searchService = new SearchService();
        searchService.init(file.getAbsolutePath());
    }
}
